package com.ease.job.quartz.service.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.Trigger;

import com.ease.common.util.Assertion;
import com.ease.job.quartz.service.CronJobExecutionService;
import com.ease.job.quartz.support.CronJobExecutor;
import com.ease.job.quartz.support.CronJobStatus;

public class CronJobExecutionServiceImpl implements CronJobExecutionService {

	private Scheduler scheduler;

	private Map<String, CronJobExecutor> cronJobExecutors = new HashMap<String, CronJobExecutor>();

	public void addJobDetail(JobDetail jobDetail, Date startTime, Date endTime, int repeatCount, long repeatInterval) {

		CronJobExecutor cronJobExecutor = new CronJobExecutor();
		cronJobExecutor.setScheduler(scheduler);
		cronJobExecutor.setJobDetail(jobDetail);

		cronJobExecutor.init();
		cronJobExecutor.reschedule(startTime, endTime, repeatCount, repeatInterval);

		addCronJobExecutor(cronJobExecutor);

		cronJobExecutor.start();
	}

	public void addJobDetail(JobDetail jobDetail, String cronExpression) {

		CronJobExecutor cronJobExecutor = new CronJobExecutor();
		cronJobExecutor.setScheduler(scheduler);
		cronJobExecutor.setJobDetail(jobDetail);

		cronJobExecutor.init();
		cronJobExecutor.reschedule(jobDetail.getName(), cronExpression);

		addCronJobExecutor(cronJobExecutor);

		cronJobExecutor.start();
	}

	public void addJobDetail(JobDetail jobDetail, Trigger trigger) {
		CronJobExecutor cronJobExecutor = new CronJobExecutor();
		cronJobExecutor.setScheduler(scheduler);
		cronJobExecutor.setJobDetail(jobDetail);

		cronJobExecutor.init();
		cronJobExecutor.reschedule(jobDetail.getName(), trigger);

		addCronJobExecutor(cronJobExecutor);

		cronJobExecutor.start();
	}

	public void addCronJobExecutor(CronJobExecutor cronJobExecutor) {
		cronJobExecutors.put(cronJobExecutor.getJobDetail().getName(), cronJobExecutor);
	}

	public CronJobExecutor getCronJobExecutor(String cronJobExecutorName) {
		CronJobExecutor cronJobExecutor = cronJobExecutors.get(cronJobExecutorName);
		Assertion.notNull(cronJobExecutor, "CronJobExecutor[cronJobExecutorName: " + cronJobExecutorName + "] not found");
		return cronJobExecutor;
	}

	// manage all jobs
	public void startAll() {
		for (CronJobExecutor cronJobExecutor : cronJobExecutors.values()) {
			cronJobExecutor.start();
		}
	}

	public void pauseAll() {
		for (CronJobExecutor cronJobExecutor : cronJobExecutors.values()) {
			cronJobExecutor.pause();
		}
	}

	public void shutdownAll() {
		for (CronJobExecutor cronJobExecutor : cronJobExecutors.values()) {
			cronJobExecutor.shutdown();
		}
	}

	// manage CronJobExecutor
	public void start(String cronJobExecutorName) {
		getCronJobExecutor(cronJobExecutorName).start();
	}

	public void pause(String cronJobExecutorName) {
		getCronJobExecutor(cronJobExecutorName).pause();
	}

	public void shutdown(String cronJobExecutorName) {
		getCronJobExecutor(cronJobExecutorName).pause();
	}

	// CronJob status
	public CronJobStatus getCronJobExecutorStatus(String cronJobExecutorName) {
		return getCronJobExecutor(cronJobExecutorName).getCronJobStatus();
	}

	public String getAllCronJobExecutorStatus() {
		StringBuilder cronJobExecutorStatus = new StringBuilder();
		for (CronJobExecutor cronJobExecutor : cronJobExecutors.values()) {
			cronJobExecutorStatus.append("{")//
					.append("cronJobExecutorName: ").append(cronJobExecutor.getJobDetail().getName()).append(",") //
					.append("cronJobExecutorStatus").append(cronJobExecutor.getCronJobStatus())//
					.append("}");
		}
		return cronJobExecutorStatus.toString();
	}

	/**
	 * @return the scheduler
	 */
	public Scheduler getScheduler() {
		return scheduler;
	}

	/**
	 * @param scheduler
	 *            the scheduler to set
	 */
	public void setScheduler(Scheduler scheduler) {
		this.scheduler = scheduler;
	}

}
